// RingBuffer.cpp
// 基于环形缓冲区的数据缓冲区实现
// 修复：使用 ringfifo.c 中的 ringget/ringput 函数，而不是独立的静态缓冲区
// 这确保了数据写入和读取使用同一个缓冲区，解决 "Invalid frame data: size=0, buffer=(nil)" 错误
// 合并自 RingBufferImpl.cpp

#include "RingBuffer.hh"
#include "../service/Logger.hh"
#include "ringfifo.h"
#include <stdio.h>
#include <string.h>
#include <stdint.h> // 添加stdint.h以支持uintptr_t类型
#include <cstdlib>  // 用于memset

// 注意：不再使用静态缓冲区，而是直接使用 ringfifo.c 中的 ringfifo 缓冲区

// 创建新的环形缓冲区实现（工厂方法）
RingBuffer* RingBuffer::createNew(int bufferSize) {
    if (bufferSize <= 0) {
        return nullptr;
    }
    
    return new RingBuffer(bufferSize);
}

// 构造函数
RingBuffer::RingBuffer(int bufferSize)
    : fBufferSize(bufferSize) {
    // 初始化底层 ringfifo 缓冲区
    // 注意：ringmalloc 应该在 VideoStreamHandler 中调用，这里只是确保已初始化
    if (bufferSize > 0) {
        // 如果 ringfifo 未初始化，这里会初始化它
        // 但通常应该在 VideoStreamHandler::initRingBuffer() 中调用 ringmalloc
    }
    reset();
}

// 析构函数
RingBuffer::~RingBuffer() {
    // 不需要释放静态内存
}

// 从缓冲区获取一帧数据
// 修复：使用 ringfifo.c 中的 ringget 函数，而不是从静态缓冲区读取
int RingBuffer::getFrame(FrameInfo& info) {
    // 初始化info结构体，确保默认值安全
    info.buffer = NULL;
    info.size = 0;
    info.frameType = 0;
    
    // 使用 ringfifo.c 中的 ringget 函数
    ringbuf ringInfo;
    ringInfo.buffer = NULL;
    ringInfo.size = 0;
    ringInfo.frame_type = 0;
    
    int result = ringget(&ringInfo);
    
    // 验证和转换
    if (result <= 0 || ringInfo.buffer == NULL || ringInfo.size <= 0) {
        // 缓冲区为空或数据无效，这是正常情况，不需要记录错误
        return 0;
    }
    
    // 验证地址有效性
    uintptr_t bufferAddr = reinterpret_cast<uintptr_t>(ringInfo.buffer);
    if (bufferAddr < 0x1000 || 
        bufferAddr > (uintptr_t)0xFFFFFFFFFFFF ||
        (bufferAddr % sizeof(void*)) != 0) {
        char logMsg[128];
        snprintf(logMsg, sizeof(logMsg), "Invalid buffer address from ringget: %p", ringInfo.buffer);
        ErrorHandler::logInfoWithNumber(ErrorNumber::ERR_BUFFER_ACCESS, logMsg);
        return 0;
    }
    
    // 安全地复制数据
    info.buffer = ringInfo.buffer;
    info.size = ringInfo.size;
    info.frameType = ringInfo.frame_type;
    
    // 记录成功获取的帧信息（调试用）
    char logMsg[128];
    snprintf(logMsg, sizeof(logMsg), "Successfully retrieved frame from ringfifo: size=%d, type=%d", info.size, info.frameType);
    ErrorHandler::logInfo(logMsg);
    
    return info.size;
}

// 向缓冲区放入一帧数据
// 修复：使用 ringfifo.c 中的 ringput 函数，而不是写入静态缓冲区
void RingBuffer::putFrame(unsigned char* buffer, int size, int frameType) {
    // 增强的输入参数验证
    if (buffer == NULL || buffer == (unsigned char*)0) {
        ErrorHandler::logInfoWithNumber(ErrorNumber::ERR_NULL_POINTER, 
            "NULL buffer pointer in RingBuffer::putFrame");
        return;
    }
    
    if (size <= 0 || size > 10 * 1024 * 1024) { // 限制最大10MB
        char logMsg[128];
        snprintf(logMsg, sizeof(logMsg), "Invalid frame size: %d in RingBuffer::putFrame", size);
        ErrorHandler::logInfoWithNumber(ErrorNumber::ERR_INVALID_SIZE, logMsg);
        return;
    }
    
    // 验证缓冲区地址的有效性
    uintptr_t bufferAddr = reinterpret_cast<uintptr_t>(buffer);
    if (bufferAddr < 0x1000 || 
        bufferAddr > (uintptr_t)0xFFFFFFFFFFFF ||
        (bufferAddr % sizeof(void*)) != 0) {
        char logMsg[128];
        snprintf(logMsg, sizeof(logMsg), "Invalid buffer address in RingBuffer::putFrame: %p", buffer);
        ErrorHandler::logInfoWithNumber(ErrorNumber::ERR_BUFFER_ACCESS, logMsg);
        return;
    }
    
    try {
        // 使用 ringfifo.c 中的 ringput 函数写入数据到 ringfifo
        // 这确保了数据写入和读取使用同一个缓冲区
        ringput(buffer, size, frameType);
    } catch (...) {
        ErrorHandler::logInfoWithNumber(ErrorNumber::ERR_MEMORY_ACCESS, 
            "Exception occurred in RingBuffer::putFrame");
    }
}

// 重置缓冲区
// 修复：使用 ringfifo.c 中的 ringreset 函数，而不是重置静态缓冲区
void RingBuffer::reset() {
    ErrorHandler::logInfoWithNumber(ErrorNumber::ERR_BUFFER_ACCESS, "Resetting ring buffer");
    // 使用 ringfifo.c 中的 ringreset 函数重置 ringfifo
    ringreset();
}

// 检查缓冲区是否有数据
// 修复：需要检查 ringfifo 中是否有数据，但由于 ringfifo.c 没有提供 hasData 函数，
// 我们通过尝试获取一帧数据来判断（但不会实际消费数据）
// 注意：这是一个简化的实现，理想情况下 ringfifo.c 应该提供 hasData 函数
bool RingBuffer::hasData() const {
    // 由于 ringfifo.c 没有提供 hasData 函数，我们无法直接检查
    // 这里返回 true，让调用者通过 getFrame 的返回值来判断
    // 理想情况下，ringfifo.c 应该提供 hasData 或类似的函数
    return true; // 总是返回 true，让调用者通过 getFrame 的返回值判断
}

